/*
 * SysPdf.java
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author gurgel
 */
public final class SmPdf implements Serializable {

    private static final Log log = LogFactory.getLog(SmPdf.class);
    private Document document = new Document();
    private PdfPTable tableActive;
    private PdfPTable nestedTableActive;
    private boolean active = false;
    private int border = 0;
    private final String FONT_DEFAULT = FontFactory.TIMES;
    private final int FONT_SIZE = 10;
    private final String FONT_TITLE = FontFactory.HELVETICA;

    /**
     * Creates a new instance of SysPdf
     */
    public SmPdf(String nmFilePdf) {
        this.setActive(this.createPdf(nmFilePdf));
    }

    private boolean createPdf(String nmFile) {
        boolean ret = false;
        if ((new File(nmFile)).exists()) {
            boolean success = (new File(nmFile)).delete();
        }
        //create pdf
        try {
            // step 2:
            // we create a writer that listens to the document and directs a PDF-stream to a file
            PdfWriter writer = PdfWriter.getInstance(getDocument(), new FileOutputStream(nmFile));
            //formating layout
            writer.setViewerPreferences(PdfWriter.PageLayoutOneColumn);
            writer.setStrictImageSequence(true);
            //Adding file meta data.
            //TODO: can expose these...
            getDocument().addTitle("SMART PjM Report");
            getDocument().addAuthor("PjM Report - John Moura");
            getDocument().addSubject("PjM report.");
            getDocument().addKeywords("Pjm, tools, report");
            getDocument().addCreator("PjM Tools Engine");
            // step 3: we open the document
            getDocument().open();
            //done!
            ret = true;
        } catch (DocumentException | IOException ex) {
            throw new UnsupportedOperationException("Something wrong of PDF file " + nmFile, ex);
        }
        return (ret);
    }

    public void writeParagraph(String text) {
        try {
            // step 4: we add a paragraph to the document
            Paragraph p1 = new Paragraph(new Chunk(text, FontFactory.getFont(FONT_TITLE, FONT_SIZE)));
            this.getDocument().add(p1);
//sample stuff
//            fox.setTextRise(superscript);
//            fox.setBackground(new Color(0xFF, 0xDE, 0xAD));
//            dog.setTextRise(subscript);
//            dog.setUnderline(new Color(0xFF, 0x00, 0x00), 3.0f, 0.0f, -5.0f + subscript, 0.0f, PdfContentByte.LINE_JOIN_BEVEL);
//            p1.add("The leading of this paragraph is calculated automagically. ");
//            p1.add("The default leading is 1.5 times the fontsize. ");
//            p1.add(new Chunk("You can add chunks "));
//            p1.add(new Phrase("or you can add phrases. "));
//            p1.add(new Phrase(
//                    "Unless you change the leading with the method setLeading, the leading doesn't change if you add " +
//                    "text with another leading. This can lead to some problems.",
//                    FontFactory.getFont(FontFactory.HELVETICA, 18)));
//            document.add(p1);
//            Paragraph p2 = new Paragraph(new Phrase(
//                    "This is my second paragraph. ", FontFactory.getFont(
//                    FontFactory.HELVETICA, 14)));
//            p2.add("As you can see, it started on a new line.");
//            document.add(p2);
//            Paragraph p3 = new Paragraph("This is my third paragraph.",
//                    FontFactory.getFont(FontFactory.HELVETICA, 12));
//            document.add(p3);
        } catch (DocumentException ex) {
            SmUtils.print(ex.getMessage());
        }
    }

    public void write(String text) {
        write(text, false);
    }

    public void write(String text, boolean bold) {
        try {
            Font font;
            if (bold) {
                font = FontFactory.getFont(FONT_DEFAULT, FONT_SIZE, Font.BOLD);
            } else {
                font = FontFactory.getFont(FONT_DEFAULT, FONT_SIZE);
            }
            Paragraph p1 = new Paragraph(new Chunk(text, font));
            p1.setAlignment(Element.ALIGN_JUSTIFIED);
            this.getDocument().add(p1);
        } catch (DocumentException de) {
            SmUtils.print(de.getMessage());
        }
    }

    public void writeTitle(String text) {
        try {
            this.getDocument().add(this.writeTitleParagraph(text));
        } catch (DocumentException de) {
            SmUtils.print(de.getMessage());
        }
    }

    public Paragraph writeTitleParagraph(String text) {
        Paragraph p1 = new Paragraph(new Chunk(
                text + "\n", FontFactory.getFont(FONT_TITLE, FONT_SIZE, Font.BOLD)));
        //p.add(new Chunk("abcdefghijklmnopqrstuvwxyz", new Font(Font.ZAPFDINGBATS, 12, Font.BOLD)));
        p1.setAlignment(Element.ALIGN_CENTER);
        return (p1);
    }

    public void write() {
        try {
            Paragraph p1 = new Paragraph(new Chunk(
                    "", FontFactory.getFont(FONT_DEFAULT, FONT_SIZE)));
            this.getDocument().add(p1);
        } catch (DocumentException de) {
            SmUtils.print(de.getMessage());
        }
    }

    public void closePdf() {
        // step 5: we close the document
        this.getDocument().close();
    }

    public void writeTable(float[] qtCols) {
        this.setTableActive(new PdfPTable(qtCols));
        this.prepareTable(this.getTableActive());
    }

    public void writeTable(int qtCols) {
        this.setTableActive(new PdfPTable(qtCols));
        this.prepareTable(this.getTableActive());
    }

    public void writeCellTitletImg(String title, String nmFile) {
        PdfPTable table = new PdfPTable(1);
        table.setWidthPercentage(40f);
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.setKeepTogether(true);
        table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
        table.getDefaultCell().setVerticalAlignment(Element.ALIGN_TOP);
        table.getDefaultCell().setBorder(getBorder());
        table.getDefaultCell().setUseBorderPadding(true);
        table.getDefaultCell().setPadding(2F);
        Paragraph paragraph = this.writeTitleParagraph(title);
        table.addCell(paragraph);

        Image png = null;
        try {
            png = Image.getInstance(nmFile);
        } catch (BadElementException ex) {
            log.error(ex);
        } catch (MalformedURLException ex) {
            log.error(ex);
        } catch (IOException ex) {
            log.error(ex);
        }
        table.addCell(png);
        this.getTableActive().addCell(table);
    }

    public void writeCell(String text) {
//        PdfPCell cell =
//                new PdfPCell(new Paragraph(text, FontFactory.getFont(FontFactory.TIMES, 10)));
        this.getTableActive().addCell(new Paragraph(text, FontFactory.getFont(FONT_DEFAULT, FONT_SIZE)));
    }

    public void writeTableClose() {
        try {
            this.getDocument().add(this.getTableActive());
            this.setTableActive(null);
        } catch (DocumentException ex) {
            log.error(ex);
        }
    }

    public Document getDocument() {
        return document;
    }

    public void setDocument(Document document) {
        this.document = document;
    }

    public void writeImg(BufferedImage imagem) {
        try {
            Image photo = Image.getInstance(imagem, null);
            //photo.setAlignment(Image.MIDDLE | Image.TEXTWRAP);
            if (photo.getWidth() > PageSize.LETTER.getWidth() - 50 || photo.getHeight() > PageSize.LETTER.getHeight() - 50) {
                photo.scaleToFit(PageSize.LETTER.getWidth() - 50, PageSize.LETTER.getHeight() - 50);
            }
            getDocument().add(photo);
        } catch (BadElementException ex) {
            log.error(ex);
        } catch (DocumentException ex) {
            log.error(ex);
        } catch (MalformedURLException ex) {
            log.error(ex);
        } catch (IOException ex) {
            log.error(ex);
        }
    }

    public void newPage() {
        this.getDocument().newPage();
    }

    public PdfPTable getTableActive() {
        return tableActive;
    }

    public void setTableActive(PdfPTable activeTable) {
        this.tableActive = activeTable;
    }

    private void prepareTable(PdfPTable table) {
        table.setWidthPercentage(100F);
        table.setSpacingBefore(12F);
        table.setSpacingAfter(12F);
        table.setHorizontalAlignment(Element.ALIGN_CENTER);
        table.setKeepTogether(true);
        this.prepareCell(table.getDefaultCell());
    }

    private void prepareCell(PdfPCell cell) {
        //default cell stats
        cell.setHorizontalAlignment(Element.ALIGN_LEFT);
        cell.setVerticalAlignment(Element.ALIGN_BASELINE);
        //cell.setGrayFill(0.8f);
        cell.setBorderColor(new BaseColor(255, 0, 0));
        //cell.setBackgroundColor(new Color(255, 0, 0));
        cell.setBorder(getBorder());
        //cell.setNoWrap(true);
        cell.setUseBorderPadding(true);
        cell.setPadding(2F);
    }

    public PdfPTable getNestedTableActive() {
        return nestedTableActive;
    }

    public void setNestedTableActive(PdfPTable nestedTable) {
        this.nestedTableActive = nestedTable;
    }

    public void writeNestedTable(float[] qtCols) {
        this.setNestedTableActive(new PdfPTable(qtCols));
        this.getNestedTableActive().setSpacingBefore(0F);
        this.getNestedTableActive().setSpacingAfter(0F);
        this.getNestedTableActive().getDefaultCell().setBorder(getBorder());
        this.getNestedTableActive().setWidthPercentage(100F);
    }

    public void writeNestedTable(int qtCols) {
        this.setNestedTableActive(new PdfPTable(qtCols));
        this.getNestedTableActive().setSpacingBefore(0F);
        this.getNestedTableActive().setSpacingAfter(0F);
        this.getNestedTableActive().getDefaultCell().setBorder(getBorder());
        this.getNestedTableActive().setWidthPercentage(100F);
    }

    public void writeNestedTableClose() {
        this.getTableActive().addCell(this.getNestedTableActive());
        this.setNestedTableActive(null);
    }

    public void writeNestedCell(String text) {
        this.getNestedTableActive().addCell(new Paragraph(text, FontFactory.getFont(FONT_DEFAULT, FONT_SIZE)));
    }

    public void writeNestedCellBold(String text) {
        this.getNestedTableActive().addCell(new Paragraph(text, FontFactory.getFont(FONT_DEFAULT, FONT_SIZE, Font.BOLD)));
    }

    public boolean isPdfActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    void writeCellBold(String text) {
        this.getTableActive().addCell(new Paragraph(text, FontFactory.getFont(FONT_DEFAULT, FONT_SIZE, Font.BOLD)));
    }

    /**
     * @return the border
     */
    public int getBorder() {
        return border;
    }

    /**
     * @param border the border to set
     */
    public void setBorder(int border) {
        this.border = border;
    }
}
